package main

import (
	"fmt"
	"github.com/Comdex/imgo"
	"github.com/gookit/color"
	"os"
	"strconv"
)

/*
首先，需要三个参数
	1. 长多少个格子
	2. 宽多少个格子
	3. 文件位置
根据图片的像素长度和宽度和长宽的格子数量，计算出每个格子的像素长度和宽度，用每个格子中心点像素的RGB值代表本格子的颜色，先把每个格子的颜色记录到数组里

从数组的【0，0】点开始从左下往右上 ↗ 方向遍历，相同颜色+1，遇到颜色与上个块不同的或者换行，则将之前记录的数量按照相应颜色进行输出
*/

func main() {
	if len(os.Args) != 4 {
		panic("参数错误")
	}
	// Row and column
	heightArgs, widthArgs, filePath := os.Args[1], os.Args[2], os.Args[3]

	height, err := strconv.Atoi(heightArgs)
	if err != nil {
		panic("第一个参数不是数字")
	}

	width, err := strconv.Atoi(widthArgs)
	if err != nil {
		panic("第二个参数不是数字")
	}

	img := imgo.MustRead(filePath)
	img = img[15 : len(img)-15]
	for i := range img {
		img[i] = img[i][15 : len(img[i])-15]
	}

	heightPx := float64(len(img)) / float64(height)
	widthPx := float64(len(img[0])) / float64(width)

	result := make([][][]uint8, height)
	for i, _ := range result {
		result[i] = make([][]uint8, width)
	}

	for i := 0; i < height; i++ {
		for j := 0; j < width; j++ {
			midH := int((float64(i) + 0.5) * heightPx)
			midW := int((float64(j) + 0.5) * widthPx)
			result[i][j] = img[midH][midW]
		}
	}

	for i := 0; i < height+width-1; i++ {
		fmt.Printf("%4d:", height+width-i-1)
		var currentH, currentW int
		currentNum := 1
		if i < height {
			currentH = i
			currentW = 0
		} else {
			currentH = height - 1
			currentW = i - currentH
		}

		if (height+width-i-1)%2 != 0 {
			// 奇数行，反过来输出
			for {
				if currentH == 0 || currentW == width-1 {
					break
				}
				currentH = currentH - 1
				currentW = currentW + 1
			}
		}
		currentColor := result[currentH][currentW]
		for {
			if (height+width-i-1)%2 != 0 {
				currentH = currentH + 1
				currentW = currentW - 1
			} else {
				currentH = currentH - 1
				currentW = currentW + 1
			}
			if currentH < 0 || currentW >= width || currentH >= height || currentW < 0 {
				//color.HEXStyle("ccc", RGB{int64(currentColor[0]), int64(currentColor[1]), int64(currentColor[2])}.rgb2hex().String()).Printf("  %d RGB: [%d,%d,%d]\n", currentNum, currentColor[0], currentColor[1], currentColor[2])
				color.HEXStyle("cca4e3", RGB{int64(currentColor[0]), int64(currentColor[1]), int64(currentColor[2])}.rgb2hex().String()).Printf("  %2d  ", currentNum)
				fmt.Println()
				//color.RGB(currentColor[0], currentColor[1], currentColor[2]).Printf("\t%d RGB: [%d,%d,%d]\n", currentNum, currentColor[0], currentColor[1], currentColor[2])
				break
			}
			if result[currentH][currentW][0] == currentColor[0] &&
				result[currentH][currentW][1] == currentColor[1] &&
				result[currentH][currentW][2] == currentColor[2] {
				currentNum++
			} else {
				// 与上一个块颜色不同
				//color.HEXStyle("ccc", RGB{int64(currentColor[0]), int64(currentColor[1]), int64(currentColor[2])}.rgb2hex().String()).Printf("  %d RGB: [%d,%d,%d]", currentNum, currentColor[0], currentColor[1], currentColor[2])
				color.HEXStyle("cca4e3", RGB{int64(currentColor[0]), int64(currentColor[1]), int64(currentColor[2])}.rgb2hex().String()).Printf("  %2d  ", currentNum)
				currentColor = result[currentH][currentW]
				currentNum = 1
			}
		}
	}

	//
	////如果读取出错会panic,返回图像矩阵img
	////img[height][width][4],height为图像高度,width为图像宽度
	////img[height][width][4]为第height行第width列上像素点的RGBA数值数组，值范围为0-255
	////如img[150][20][0]是150行20列处像素的红色值,img[150][20][1]是150行20列处像素的绿
	////色值，img[150][20][2]是150行20列处像素的蓝色值,img[150][20][3]是150行20列处像素
	////的alpha数值,一般用作不透明度参数,如果一个像素的alpha通道数值为0%，那它就是完全透明的.
	//img := imgo.MustRead("./a.jpg")
	//
	////对原图像矩阵进行日落效果处理
	//img2 := imgo.SunsetEffect(img)
	//
	////保存为jpeg,100为质量，1-100
	//err := imgo.SaveAsJPEG("example/new.jpg", img2, 100)
	//if err != nil {
	//	panic(err)
	//}
}

type RGB struct {
	red, green, blue int64
}

type HEX struct {
	str string
}

func (color HEX) String() string {
	return "#" + color.str
}

func t2x(t int64) string {
	result := strconv.FormatInt(t, 16)
	if len(result) == 1 {
		result = "0" + result
	}
	return result
}

func (color RGB) rgb2hex() HEX {
	r := t2x(color.red)
	g := t2x(color.green)
	b := t2x(color.blue)
	return HEX{r + g + b}
}

func (color HEX) hex2rgb() RGB {
	r, _ := strconv.ParseInt(color.str[:2], 16, 10)
	g, _ := strconv.ParseInt(color.str[2:4], 16, 18)
	b, _ := strconv.ParseInt(color.str[4:], 16, 10)
	return RGB{r, g, b}
}
